;****************************************************************************
;* Copyright (C) 2012 Maxim Integrated Products, All Rights Reserved.
;*
;* Permission is hereby granted, free of charge, to any person obtaining a
;* copy of this software and associated documentation files (the "Software"),
;* to deal in the Software without restriction, including without limitation
;* the rights to use, copy, modify, merge, publish, distribute, sublicense,
;* and/or sell copies of the Software, and to permit persons to whom the
;* Software is furnished to do so, subject to the following conditions:
;*
;* The above copyright notice and this permission notice shall be included
;* in all copies or substantial portions of the Software.
;*
;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
;* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;* MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
;* IN NO EVENT SHALL MAXIM INTEGRATED PRODUCTS BE LIABLE FOR ANY CLAIM, DAMAGES
;* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
;* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
;* OTHER DEALINGS IN THE SOFTWARE.
;*
;* Except as contained in this notice, the name of Maxim Integrated Products
;* shall not be used except as stated in the Maxim Integrated Products
;* Branding Policy.
;*
;* The mere transfer of this software does not imply any licenses
;* of trade secrets, proprietary technology, copyrights, patents,
;* trademarks, maskwork rights, or any other form of intellectual
;* property whatsoever. Maxim Integrated Products retains all ownership rights.
;*
;*     Description: Implements functions for performing operations on the MAXQ
;*                  embedded Flash memory.
;*             $Id: maxq622_flash.asm 3409 2012-03-11 18:19:14Z jbrodt $
;*
;********************************************************************************

; Utility ROM function word addresses
; Assembler assumes byte address so shift by 1
#define UROM_flashWrite         (08033h << 1)
#define UROM_flashErasePage     (08035h << 1)

#ifdef __IAR_SYSTEMS_ASM__
#define _flash_erase_page       flash_erase_page
#define _flash_write_word       flash_write_word
#define _flash_write_dbl_word   flash_write_dbl_word
#define _flash_read_word        flash_read_word
#define PARAM_REGISTER          A[0]
#define RETURN_REGISTER         A[0]
#define SCRATCH_ACCUMULATOR     1
#else
#define PARAM_REGISTER          A[7]
#define RETURN_REGISTER         A[7]
#define SCRATCH_ACCUMULATOR     6
#endif

  RSEG CODE

;*******************************************************************************
; int flash_erase_page(unsigned int address);
  public _flash_erase_page
_flash_erase_page:

#ifdef __IAR_SYSTEMS_ASM__
  ; address for erase is already in A[0]
#else
  push A[0]
  ; address to erase is in A[7]
  move A[0], A[7]
#endif

  lcall UROM_flashErasePage

  ; if error return 0
  jump nc, _flash_erase_page_done
  move RETURN_REGISTER, #0
  jump _flash_erase_page_exit
_flash_erase_page_done:
  move RETURN_REGISTER, #1
_flash_erase_page_exit:

#ifndef __IAR_SYSTEMS_ASM__
  pop A[0]
#endif

  ret


;*******************************************************************************
; int flash_write_dbl_word(unsigned int address, unsigned int low_word, unsigned int high_word);
  public _flash_write_dbl_word
_flash_write_dbl_word:

#ifdef __IAR_SYSTEMS_ASM__
  ; address to write is already in A[0]
  ; value to write is already in A[1]
  ; value to write is already in A[2]
#else
  push A[0]
  push A[1]
  push A[2]
  ; address to write is in A[7]
  move A[0], A[7]
  ; value to write is in A[6]
  move A[1], A[6]
  ; value to write is in A[5]
  move A[2], A[5]
#endif

  lcall UROM_flashWrite

  ; if error return 0
  jump nc, _flash_write_word_done
  move RETURN_REGISTER, #0
  jump _flash_write_word_exit
_flash_write_word_done:
  move RETURN_REGISTER, #1
_flash_write_word_exit:

#ifndef __IAR_SYSTEMS_ASM__
  pop A[2]
  pop A[1]
  pop A[0]
#endif

  ret


;*******************************************************************************
; unsigned int flash_read_word(unsigned int address);
  public _flash_read_word
_flash_read_word:

  push  DPC

  ; setup CP for word mode
  move  AP, #SCRATCH_ACCUMULATOR
  move  ACC, DPC
  or    #00040h
  move  DPC, ACC

  move CP, PARAM_REGISTER
  move RETURN_REGISTER, @CP
  pop DPC

  ret

  END
